#include <casensoruni/CASensorUniE.h>

// ***********************************************************************

// class EDROOMTopContext

// ***********************************************************************



	// CONSTRUCTORES***********************************************

CASensorUni::EDROOMTopContext::EDROOMTopContext (CASensorUni &act, FrameTypeReceived_t & EDROOMpVarVFrameType, int & EDROOMpVarVMessageNumber, CEDROOMPOOLCDFrame & EDROOMpPoolCDFrame ):

	EDROOMcomponent(act)
	,Msg(EDROOMcomponent.Msg)
	,MsgBack(EDROOMcomponent.MsgBack)
	,Timer(EDROOMcomponent.Timer)
	,Ssi(EDROOMcomponent.Ssi)
	, VFrameType ( EDROOMpVarVFrameType )
	, VMessageNumber ( EDROOMpVarVMessageNumber )
	, CEDROOMPoolCDFrame ( EDROOMpPoolCDFrame )
 {

}

CASensorUni::EDROOMTopContext::EDROOMTopContext ( EDROOMTopContext &contex ):

	EDROOMcomponent(contex.EDROOMcomponent),
	Msg(contex.Msg),
	MsgBack(contex.MsgBack)
	,Timer(contex.Timer)
	,Ssi(contex.Ssi)
	, VFrameType ( contex.VFrameType )
	, VMessageNumber ( contex.VMessageNumber )
	, CEDROOMPoolCDFrame ( contex.CEDROOMPoolCDFrame )
 {

}

	// EDROOMSearchContextTrans********************************************

bool CASensorUni::EDROOMTopContext::EDROOMSearchContextTrans(TEDROOMTransId &edroomCurrentTrans){

	bool edroomValidMsg=false; 

	 switch(Msg->signal){

		 case ( EDROOMSignalDestroy ): 

			 edroomValidMsg=true;
			 edroomCurrentTrans.distanceToContext = 0 ;
			 edroomCurrentTrans.localId = -1 ;
			 break;

	}

	return(edroomValidMsg);

}

	// Funciones Definidas por el usuario  ****************************

bool_t	CASensorUni::EDROOMTopContext::FGetFrames(TEDROOMInt32 num,byte_t *message)

{
 	FILE *fich;
	char ruteFile[50];
	byte_t aux[10];
  
	strcpy(ruteFile,"UpFrames/");
	FIntToChar(num,aux);
	strcat(ruteFile,(char *)aux);
    
	fich=fopen(ruteFile,"rb");    
   if (fich==NULL)
   {
   	return false;
   }
   else
   {
		 fread(message,1,50,fich);
 	}
  fclose(fich);
  return true;
}
 



void	CASensorUni::EDROOMTopContext::FIntToChar(TEDROOMInt32 num,byte_t * cConvert)

 
{
 
	byte_t aux;
	TEDROOMInt32 i=0;
	TEDROOMInt32 j;
	
	do
	{ 
		cConvert[i++]= (num % 10) + '0';
		num=num/10;
	}
	while (num>0);
	cConvert[i--]='\0';
	j=0;
	for (;i>j;i--,j++)
	{
		aux=cConvert[i];
		cConvert[i]=cConvert[j];
		cConvert[j]=aux;
	}
}



void	CASensorUni::EDROOMTopContext::FSendFrame()

{
	bool_t cont;
 
	CDFrame * ap_CDFrame = CEDROOMPoolCDFrame.AllocData();
	cont=FGetFrames(VMessageNumber,ap_CDFrame->dataFrame);
	VFrameType=get_frame_type(ap_CDFrame->dataFrame);

	VMessageNumber++;
	if (!cont)
	{
		VMessageNumber=-1;
	}
	else
	{
		Ssi.send(SDataFrame, EDROOMprioNormal, ap_CDFrame, &CEDROOMPoolCDFrame);
	}

 
}



void	CASensorUni::EDROOMTopContext::FTimeSend()

{
    if (VMessageNumber!=-1)
    {
  // //printf("SENSOR UNIDIRECCIONAL: Standby\n");
   	Pr_Time	interval(0.01); // Declare time var with an initial value in seconds
	Timer.InformIn( interval, EDROOMprioNormal );
    }
 
}
 



	//*****Pools

	//CEDROOMPOOLCDFrame

CASensorUni::EDROOMTopContext::CEDROOMPOOLCDFrame::CEDROOMPOOLCDFrame(unsigned int elemCount, CDFrame* pMem, bool_t * pMemMarks):CEDROOMProtectedMemoryPool(elemCount, pMem, pMemMarks, sizeof (CDFrame)){;}

CDFrame *	CASensorUni::EDROOMTopContext::CEDROOMPOOLCDFrame::AllocData(){
	return(CDFrame*)CEDROOMProtectedMemoryPool::AllocData();
}



// ***********************************************************************

// class EDROOMTopState

// ***********************************************************************



	// CONSTRUCTOR*************************************************

CASensorUni::EDROOMTopState::EDROOMTopState (CASensorUni &act, CEDROOMMemory *pEDROOMMemory  ):
	  EDROOMTopContext( act , VFrameType, VMessageNumber,CEDROOMPoolCDFrame )
	, VFrameType (   )
	, VMessageNumber ( 1 )
	, CEDROOMPoolCDFrame ( 200, pEDROOMMemory->poolCDFrame, pEDROOMMemory->poolMarkCDFrame)
{

}

	// EDROOMBehaviour**********************************************

void CASensorUni::EDROOMTopState::EDROOMBehaviour(){

	TEDROOMTransId edroomCurrentTrans;

	edroomCurrentTrans = EDROOMIllegada();

	do{

		switch(edroomCurrentTrans.localId){

			case(Init):
				edroomNextState = Ready;
				break;
			case(SendFrame):
				FSendFrame();
				edroomNextState = Ready;
				break;
		}

		EDROOMcomponent.EDROOMTraceStateEntry();

		EDROOMcomponent.EDROOMTraceStateEntry();

		switch(edroomNextState){

			case(I):
				edroomCurrentTrans=EDROOMIllegada();
				break;

			case(Ready):
				FTimeSend();
				edroomCurrentTrans=EDROOMReadyllegada();
				break;

		}

		EDROOMcomponent.EDROOMTraceStateExit();

		edroomCurrentState=edroomNextState;

	}while(Msg->signal != EDROOMSignalDestroy);

}



	// Inicio**********************************************

void CASensorUni::EDROOMTopState::EDROOMInicio(){

edroomCurrentState=I;

}



//	 ***********************************************************************

//	 llegada SubEstado I

//	 ***********************************************************************



TEDROOMTransId CASensorUni::EDROOMTopState::EDROOMIllegada(){

	TEDROOMTransId edroomCurrentTrans;

	edroomCurrentTrans.localId = Init;
	edroomCurrentTrans.distanceToContext = 0;
	EDROOMcomponent.EDROOMTraceTrans(edroomCurrentTrans, 0);

	return(edroomCurrentTrans);

}



	// ***********************************************************************

	// llegada SubEstado Hoja Ready

	// ***********************************************************************



TEDROOMTransId CASensorUni::EDROOMTopState::EDROOMReadyllegada(){

	TEDROOMTransId edroomCurrentTrans;

	int edroomValidMsg=false;

	do{

		EDROOMNuevoMens ();

		switch(Msg->signal){

			case (EDROOMSignalTimeout): 

				 if ( *Msg->GetPInterface() == Timer) {

					edroomCurrentTrans.localId= SendFrame;
					edroomCurrentTrans.distanceToContext = 0;
					edroomValidMsg=true;
				 }

				break;

		};

		if (!edroomValidMsg) edroomValidMsg = EDROOMSearchContextTrans(edroomCurrentTrans);

	} while (!edroomValidMsg);

	EDROOMcomponent.EDROOMTraceTrans(edroomCurrentTrans, Msg->signal);

	return(edroomCurrentTrans);

}



